<template>
  <div class="folder-tree">
    <div class="tree-header">
      <h3 class="tree-title">
        <el-icon><Folder /></el-icon>
        {{ t('folderTree.title') }}
      </h3>
      <el-button 
        size="small" 
        text 
        :icon="Refresh" 
        @click="refreshTree"
        :title="t('folderTree.refreshTooltip')"
      />
    </div>
    
    <div class="tree-content">
      <!-- 根目录快捷导航 -->
      <div class="root-navigation">
        <el-button
          class="root-nav-btn"
          :class="{ active: currentFolderId === 0 }"
          size="small"
          text
          @click="navigateToRoot"
        >
          <el-icon><HomeFilled /></el-icon>
          <span>{{ t('folderTree.allFiles') }}</span>
        </el-button>
      </div>

      <!-- 拖拽状态提示 -->
      <div v-if="isDragging" class="drag-overlay">
        <div class="drag-message">
          <el-icon class="loading-icon"><Loading /></el-icon>
          {{ dragPreview }}
        </div>
      </div>

      <el-tree
        ref="treeRef"
        :data="treeData"
        :props="treeProps"
        :load="loadNode"
        :expand-on-click-node="false"
        :check-on-click-node="false"
        node-key="id"
        lazy
        draggable
        @node-click="handleNodeClick"
        @node-expand="handleNodeExpand"
        @node-collapse="handleNodeCollapse"
        @node-drop="handleNodeDrop"
        :allow-drop="allowDrop"
        :allow-drag="allowDrag"
      >
        <template #default="{ node, data }">
          <div class="tree-node" @contextmenu.prevent="handleContextMenu($event, node, data)">
            <div class="node-content">
              <el-icon class="folder-icon">
                <Folder v-if="!node.expanded" />
                <FolderOpened v-else />
              </el-icon>
              <span class="node-label">{{ node.label }}</span>
              <span class="file-count" v-if="data.fileCount > 0">({{ data.fileCount }})</span>
            </div>
            
            <!-- 节点操作按钮 -->
            <div class="node-actions" v-show="hoveredNodeId === data.id">
              <el-button
                size="small"
                text
                :icon="Edit"
                @click.stop="handleRename(data)"
                :title="t('folderTree.rename')"
              />
              <el-button
                size="small"
                text
                :icon="Delete"
                @click.stop="handleDelete(data)"
                :title="t('folderTree.delete')"
                type="danger"
              />
            </div>
          </div>
        </template>
      </el-tree>
    </div>

    <!-- 右键菜单 -->
    <div
      v-if="contextMenuVisible"
      class="context-menu"
      :style="{
        left: contextMenuPosition.x + 'px',
        top: contextMenuPosition.y + 'px'
      }"
      @click.stop
    >
      <div class="context-menu-item" @click="selectedNode && handleRename(selectedNode); contextMenuVisible = false">
        <el-icon><Edit /></el-icon>
        {{ t('folderTree.rename') }}
      </div>
      <div class="context-menu-item" @click="selectedNode && handleRefresh(selectedNode); contextMenuVisible = false">
        <el-icon><Refresh /></el-icon>
        {{ t('folderTree.refresh') }}
      </div>
      <div class="context-menu-divider"></div>
      <div class="context-menu-item danger" @click="selectedNode && handleDelete(selectedNode); contextMenuVisible = false">
        <el-icon><Delete /></el-icon>
        {{ t('folderTree.delete') }}
      </div>
    </div>

    <!-- 重命名对话框 -->
    <el-dialog
      v-model="renameDialogVisible"
      :title="t('folderTree.renameDialogTitle')"
      width="400px"
      :before-close="handleRenameCancel"
    >
      <el-form @submit.prevent="handleRenameConfirm">
        <el-form-item :label="t('folderTree.folderNameLabel')">
          <el-input
            ref="renameInputRef"
            v-model="newFolderName"
            :placeholder="t('folderTree.folderNamePlaceholder')"
            maxlength="100"
            show-word-limit
            @keyup.enter="handleRenameConfirm"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="handleRenameCancel">{{ t('folderTree.cancel') }}</el-button>
        <el-button type="primary" @click="handleRenameConfirm" :loading="renameLoading">
          {{ t('folderTree.confirm') }}
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from 'vue'
import { useI18n } from 'vue-i18n'
import { ElMessage, ElMessageBox, ElTree } from 'element-plus'
import {
  Folder,
  FolderOpened,
  Edit,
  Delete,
  Refresh,
  Loading,
  HomeFilled
} from '@element-plus/icons-vue'
// import { folderApi } from '@/api/modules/folder'
import axios from 'axios'

const { t } = useI18n()

// 简化的Node类型定义，避免与Element Plus内部类型耦合
interface SimpleNode {
  level: number
  data: TreeNodeData
  parent?: SimpleNode
}

// 组件属性
interface Props {
  currentFolderId?: number | null
}

const props = withDefaults(defineProps<Props>(), {
  currentFolderId: null
})

// 组件事件
const emit = defineEmits<{
  folderClick: [folderId: number, folderPath: string]
  folderRename: [folderId: number, newName: string]
  folderDelete: [folderId: number]
  folderMove: [folderId: number, targetParentId: number]
}>()

// 树形数据接口
interface TreeNodeData {
  id: number
  label: string
  parentId?: number
  fileCount: number
  hasChildren: boolean
  isLeaf?: boolean
  children?: TreeNodeData[]
}

// 响应式数据
const treeRef = ref<InstanceType<typeof ElTree>>()
const renameInputRef = ref()

const treeData = ref<TreeNodeData[]>([])
const hoveredNodeId = ref<number | null>(null)
const selectedNode = ref<TreeNodeData | null>(null)

// 右键菜单状态
const contextMenuVisible = ref(false)
const contextMenuPosition = ref({ x: 0, y: 0 })

// 重命名相关
const renameDialogVisible = ref(false)
const newFolderName = ref('')
const renameLoading = ref(false)
const renamingNode = ref<TreeNodeData | null>(null)

// 树形组件配置
const treeProps = {
  children: 'children',
  label: 'label',
  isLeaf: 'isLeaf'
}

// 获取认证token
const getToken = () => {
  return localStorage.getItem('token')
}

// 加载树节点数据
const loadNode = async (node: any, resolve: (data: TreeNodeData[]) => void) => {
  try {
    const parentId = node.level === 0 ? null : node.data?.id

    // 调用后端API获取文件夹树（使用tree端点，depth=1只获取直接子节点）
    const response = await axios.get('http://localhost:8080/api/folders/tree', {
      params: {
        parentId: parentId,  // null表示根目录
        depth: 1  // 只获取一层，实现懒加载
      },
      headers: {
        'Authorization': `Bearer ${getToken()}`
      }
    })

    if (response.status === 200 && response.data.code === 200) {
      const treeData = response.data.data || []

      // tree端点返回的是树形结构，我们需要提取直接子节点
      const treeNodes: TreeNodeData[] = treeData.map((folder: any) => ({
        id: folder.id,
        label: folder.name,
        parentId: folder.parentId,
        fileCount: folder.fileCount || 0,
        hasChildren: folder.hasChildren,
        isLeaf: !folder.hasChildren // 根据hasChildren判断是否为叶子节点
      }))

      // el-tree的bug，有时需要手动刷新
      await nextTick()
      treeRef.value?.store.setData(treeNodes)

      resolve(treeNodes)
    } else {
      console.error(`加载文件夹树数据失败: ${response.data?.message}`)
      ElMessage.error(t('folderTree.error.loadFailed'))
      resolve([])
    }
  } catch (err) {
    console.error('加载文件夹树数据异常:', err)
    ElMessage.error(t('folderTree.error.loadFailed'))
    resolve([])
  }
}

// 节点点击事件
const handleNodeClick = (data: TreeNodeData, node: any) => {
  console.log('点击文件夹:', data.label)
  
  // 构建文件夹路径
  const path = buildFolderPath(node)
  
  // 触发文件夹切换事件
  emit('folderClick', data.id, path)
}

// 构建文件夹路径
const buildFolderPath = (node: any): string => {
  const pathParts: string[] = []
  let currentNode = node
  
  while (currentNode) {
    if (currentNode.data) {
      pathParts.unshift(currentNode.data.label)
    }
    currentNode = currentNode.parent
  }
  
  return pathParts.join('/')
}

// 节点展开事件
const handleNodeExpand = (data: TreeNodeData, node: any) => {
  console.log('展开文件夹:', data.label)
}

// 节点收起事件
const handleNodeCollapse = (data: TreeNodeData, node: any) => {
  console.log('收起文件夹:', data.label)
}

// 拖拽相关
const isDragging = ref(false)
const dragPreview = ref<string>('')

const allowDrop = (draggingNode: any, dropNode: any, type: string) => {
  // 只允许拖拽到文件夹内部
  if (type !== 'inner') return false

  const dragData = draggingNode.data as TreeNodeData
  const dropData = dropNode.data as TreeNodeData

  // 不能拖拽到自己
  if (dragData.id === dropData.id) return false

  // 不能拖拽到自己的子文件夹中（防止循环引用）
  if (isDescendant(dropData.id, dragData.id)) return false

  return true
}

const allowDrag = (draggingNode: any) => {
  // 根文件夹不允许拖拽
  if (draggingNode.level <= 1) return false

  // 可以添加更多拖拽限制条件
  return true
}

// 检查是否是子文件夹（防止循环引用）
const isDescendant = (ancestorId: number, descendantId: number): boolean => {
  // 这里简化处理，实际应该递归检查整个树结构
  // 在实际项目中，可以通过API调用后端来验证
  return false
}

const handleNodeDrop = async (draggingNode: any, dropNode: any, dropType: 'before' | 'after' | 'inner') => {
  try {
    const draggedFolderId = draggingNode.data.id
    let targetParentId = dropNode.data.id

    if (dropType !== 'inner') {
      targetParentId = dropNode.data.parentId || 0 // 移到根目录
    }

    // 防止移动到自身或子节点下
    let tempNode = dropNode
    while(tempNode) {
      if(tempNode.data.id === draggedFolderId) {
        ElMessage.error(t('folderTree.error.moveToChild'))
        // 如何恢复树的状态？el-tree没有提供简便方法，暂时刷新
        refreshTree() 
        return
      }
      tempNode = tempNode.parent
    }

    // 调用API移动文件夹
    const response = await axios.put(
      `http://localhost:8080/api/folders/${draggedFolderId}/move`,
      { targetParentId: targetParentId === 0 ? null : targetParentId },
      { headers: { 'Authorization': `Bearer ${getToken()}` } }
    )

    if (response.status === 200 && response.data.code === 200) {
      ElMessage.success(response.data.message || '移动成功') // API可能返回具体消息
      emit('folderMove', draggedFolderId, targetParentId)
    } else {
      ElMessage.error(t('folderTree.error.moveFailed'))
      refreshTree()
    }
  } catch (error: any) {
    console.error('移动文件夹出错:', error)
    ElMessage.error(error.response?.data?.message || t('folderTree.error.moveFailed'))
    refreshTree()
  }
}

// 右键菜单
const handleContextMenu = (event: MouseEvent, node: any, data: TreeNodeData) => {
  event.preventDefault()
  event.stopPropagation()

  selectedNode.value = data

  // 计算菜单位置，考虑边界检测
  const menuWidth = 200 // 预估菜单宽度
  const menuHeight = 200 // 预估菜单高度

  let x = event.clientX
  let y = event.clientY

  // 右边界检测
  if (x + menuWidth > window.innerWidth) {
    x = window.innerWidth - menuWidth - 10
  }

  // 下边界检测
  if (y + menuHeight > window.innerHeight) {
    y = window.innerHeight - menuHeight - 10
  }

  // 确保不超出左上边界
  x = Math.max(10, x)
  y = Math.max(10, y)

  contextMenuPosition.value = { x, y }
  contextMenuVisible.value = true

  // 点击其他地方关闭菜单
  const closeMenu = () => {
    contextMenuVisible.value = false
    document.removeEventListener('click', closeMenu)
  }

  setTimeout(() => {
    document.addEventListener('click', closeMenu)
  }, 100)
}

// 重命名文件夹
const handleRename = (data: TreeNodeData) => {
  renamingNode.value = data
  newFolderName.value = data.label
  renameDialogVisible.value = true
  
  nextTick(() => {
    renameInputRef.value?.focus()
    renameInputRef.value?.select()
  })
}

const handleRenameConfirm = async () => {
  if (!newFolderName.value.trim()) {
    ElMessage.warning(t('folderTree.error.nameRequired'))
    return
  }
  if (newFolderName.value.length > 100) {
    ElMessage.warning(t('folderTree.error.nameTooLong'))
    return
  }
  // 简单的特殊字符校验
  const invalidChars = /[\\/:"*?<>|]/
  if (invalidChars.test(newFolderName.value)) {
    ElMessage.warning(t('folderTree.error.nameInvalidChars'))
    return
  }
  
  renameLoading.value = true
  try {
    if (renamingNode.value) {
      const response = await axios.put(
        `http://localhost:8080/api/folders/${renamingNode.value.id}`,
        { name: newFolderName.value },
        { headers: { 'Authorization': `Bearer ${getToken()}` } }
      )
      
      if (response.status === 200 && response.data.code === 200) {
        // 更新树节点
        const node = treeRef.value?.getNode(renamingNode.value.id)
        if (node) {
          node.data.label = newFolderName.value
        }
        ElMessage.success(t('folderTree.renameSuccess'))
        emit('folderRename', renamingNode.value.id, newFolderName.value)
        handleRenameCancel()
      } else {
        ElMessage.error(t('folderTree.renameFail'))
      }
    }
  } catch (error: any) {
    console.error('重命名文件夹出错:', error)
    ElMessage.error(error.response?.data?.message || t('folderTree.renameFail'))
  } finally {
    renameLoading.value = false
  }
}

const handleRenameCancel = () => {
  renameDialogVisible.value = false
  newFolderName.value = ''
  renamingNode.value = null
}

// 删除文件夹
const handleDelete = (data: TreeNodeData) => {
  ElMessageBox.confirm(
    t('folderTree.deleteConfirmText'),
    t('folderTree.deleteConfirmTitle'),
    {
      confirmButtonText: t('folderTree.confirm'),
      cancelButtonText: t('folderTree.cancel'),
      type: 'warning',
    }
  ).then(() => {
    handleDeleteConfirm(data)
  }).catch(() => {
    ElMessage.info(t('folderTree.deleteCancelled'))
  })
}

// 刷新相关
const handleRefresh = (data: TreeNodeData) => {
  refreshTree()
}

const refreshTree = () => {
  // 重新加载整个树
  treeData.value = []

  // 触发重新加载
  nextTick(() => {
    loadNode({ level: 0 }, (data) => {
      treeData.value = data
    })
  })

  ElMessage.success('文件夹树已刷新')
}

// 导航到根目录
const navigateToRoot = () => {
  emit('folderClick', 0, '全部文件')
}

// 组件挂载
onMounted(() => {
  // 初始化加载根文件夹
  loadNode({ level: 0 }, (data: TreeNodeData[]) => {
    treeData.value = data
  })
})

// 暴露方法给父组件
defineExpose({
  refreshTree,
  expandNode: (nodeId: number) => {
    const node = treeRef.value?.getNode(nodeId)
    if (node) {
      node.expand()
    }
  },
  selectNode: (nodeId: number) => {
    treeRef.value?.setCurrentKey(nodeId)
  }
})

// 删除确认
const handleDeleteConfirm = async (folder: TreeNodeData) => {
  try {
    const response = await axios.delete(`http://localhost:8080/api/folders/${folder.id}`, {
      headers: { 'Authorization': `Bearer ${getToken()}` }
    })
    if (response.status === 200 && response.data.code === 200) {
      ElMessage.success(t('folderTree.deleteSuccess'))
      // 从树中移除节点
      treeRef.value?.remove(folder)
      emit('folderDelete', folder.id)
    } else {
      ElMessage.error(t('folderTree.deleteFail'))
    }
  } catch (error) {
    console.error('删除文件夹出错:', error)
    ElMessage.error(t('folderTree.deleteFail'))
  }
}
</script>

<style lang="scss" scoped>
.folder-tree {
  height: 100%;
  display: flex;
  flex-direction: column;
  background-color: var(--bg-color-tertiary);
  border-right: 1px solid var(--border-color-light);
  transition: all 0.3s ease;
}

.tree-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px;
  border-bottom: 1px solid var(--border-color-light);
  background-color: var(--bg-color-secondary);
  transition: all 0.3s ease;

  .tree-title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--text-color-primary);
    transition: color 0.3s ease;
  }
}

.tree-content {
  flex: 1;
  overflow: auto;
  padding: 0;
}

.root-navigation {
  padding: 8px 12px;
  border-bottom: 1px solid var(--border-color-light);
  background-color: var(--bg-color-secondary);
  transition: all 0.3s ease;

  .root-nav-btn {
    width: 100%;
    justify-content: flex-start;
    padding: 8px 12px;
    border-radius: 6px;
    transition: all 0.3s ease;
    color: var(--text-color-primary);

    &:hover {
      background-color: var(--theme-primary-bg);
      color: var(--theme-primary);
    }

    &.active {
      background-color: var(--theme-primary);
      color: white;

      &:hover {
        background-color: var(--theme-primary-dark);
      }
    }

    .el-icon {
      margin-right: 8px;
      font-size: 16px;
    }

    span {
      font-size: 14px;
      font-weight: 500;
    }
  }
}

.tree-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 4px 8px;
  border-radius: 6px;
  transition: background-color 0.2s;
  
  &:hover {
    background-color: var(--bg-color-secondary);
  }
  
  .node-content {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1;
    min-width: 0;
    
    .folder-icon {
      font-size: 16px;
      color: var(--color-warning);
      flex-shrink: 0;
      transition: color 0.3s ease;
    }

    .node-label {
      flex: 1;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      font-size: 14px;
      color: var(--text-color-primary);
      transition: color 0.3s ease;
    }

    .file-count {
      font-size: 12px;
      color: var(--text-color-secondary);
      flex-shrink: 0;
      transition: color 0.3s ease;
    }
  }
  
  .node-actions {
    display: flex;
    gap: 4px;
    opacity: 0;
    transition: opacity 0.2s;
    
    .el-button {
      padding: 4px;
      min-height: auto;
    }
  }
  
  &:hover .node-actions {
    opacity: 1;
  }
}

:deep(.el-tree-node__content) {
  padding: 0 !important;
  height: auto !important;
}

:deep(.el-tree-node__expand-icon) {
  padding: 4px;
  font-size: 12px;
}

.danger-item {
  color: var(--color-danger);
  transition: color 0.3s ease;
}

/* 拖拽状态样式 */
.drag-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  border-radius: 6px;
}

.drag-message {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  background-color: var(--theme-primary);
  color: white;
  border-radius: 6px;
  font-size: 14px;
  box-shadow: var(--shadow-base);
  transition: all 0.3s ease;
}

.loading-icon {
  animation: rotate 1s linear infinite;
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

/* 拖拽时的树节点样式 */
:deep(.el-tree-node.is-dragging) {
  opacity: 0.6;
}

:deep(.el-tree-node.is-drop-target) {
  background-color: var(--theme-primary-bg);
  border: 2px dashed var(--theme-primary);
  border-radius: 4px;
}

// 调整el-tree的padding
:deep(.el-tree) {
  padding: 8px;
}

/* 右键菜单样式 */
.context-menu {
  position: fixed;
  background-color: var(--bg-color-tertiary);
  border: 1px solid var(--border-color-light);
  border-radius: 8px;
  box-shadow: var(--shadow-base);
  padding: 8px 0;
  z-index: 99999;
  min-width: 160px;
  max-width: 200px;
  pointer-events: auto;
  transition: all 0.3s ease;
}

.context-menu-item {
  display: flex;
  align-items: center;
  padding: 8px 16px;
  cursor: pointer;
  font-size: 14px;
  color: var(--text-color-primary);
  transition: all 0.3s ease;

  &:hover {
    background-color: var(--bg-color-secondary);
    color: var(--theme-primary);
  }

  &.danger {
    color: var(--color-danger);

    &:hover {
      background-color: rgba(239, 68, 68, 0.1);
      color: var(--color-danger);
    }
  }

  .el-icon {
    margin-right: 8px;
    font-size: 16px;
  }
}

.context-menu-divider {
  height: 1px;
  background-color: var(--border-color-light);
  margin: 4px 0;
  transition: background-color 0.3s ease;
}
</style>
